/*
 * Copyright 2015-2102 Fast(http://www.cloudate.net) Group.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fast.pay.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.fast.pay.common.core.enums.PublicEnum;
import com.fast.pay.common.core.enums.TradeStatusEnum;
import com.fast.pay.common.core.exception.BizException;
import com.fast.pay.common.core.utils.DateUtils;
import com.fast.pay.controller.common.BaseController;
import com.fast.pay.service.CnpPayService;
import com.fast.pay.trade.entity.RpTradePaymentRecord;
import com.fast.pay.trade.exception.TradeBizException;
import com.fast.pay.trade.service.RpTradePaymentManagerService;
import com.fast.pay.trade.service.RpTradePaymentQueryService;
import com.fast.pay.trade.utils.MerchantApiUtil;
import com.fast.pay.trade.vo.ScanPayResultVo;
import com.fast.pay.user.entity.RpUserPayConfig;
import com.fast.pay.user.exception.UserBizException;
import com.fast.pay.user.service.RpUserPayConfigService;
import com.fast.pay.utils.JsonUtils;

@Controller
@RequestMapping(value = "/scanPay")
public class ScanPayController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(ScanPayController.class);


    @Autowired
    private RpTradePaymentManagerService rpTradePaymentManagerService;

    @Autowired
    private RpTradePaymentQueryService rpTradePaymentQueryService;

    @Autowired
    private RpUserPayConfigService rpUserPayConfigService;

    @Autowired
    private CnpPayService cnpPayService;


    /**
     * 扫码支付,预支付页面
     * 用户进行扫码支付时,商户后台调用该接口
     * 支付平台根据商户传入的参数是否包含支付通道,决定需要跳转的页面
     * 1:传入支付通道参数,跳转到相应的支付通道扫码页面
     * 2:未传入支付通道参数,跳转到
     *
     * @return
     * @throws IOException 
     */
    @RequestMapping("/initPay")
    public void initPay(HttpServletResponse httpServletResponse ,HttpServletRequest httpServletRequest) throws IOException {
    	httpServletRequest.setCharacterEncoding("utf-8");
    	Map<String, String> resMap = new HashMap<String, String>();
    	resMap.put("apiCode", PublicEnum.NO.toString()); //默认成功
    	resMap.put("apiMsg", "操作成功"); //默认成功
        Map<String, String> paramMap = new TreeMap<String, String>();
        //获取商户传入参数
        String payKey = getString("payKey"); // 企业支付KEY
        paramMap.put("payKey", payKey);
        String goodsName = getString("goodsName"); // 商品名称
        paramMap.put("goodsName", goodsName);
        String orderNo = getString("orderNo"); // 订单编号
        paramMap.put("orderNo", orderNo);
        String orderAmountStr = getString("orderAmount"); // 订单金额 , 单位:元
        paramMap.put("orderAmount", orderAmountStr);
        
        //这里要获得请求IP
        String orderIp = getString("orderIp"); // 下单IP
        paramMap.put("orderIp", orderIp);
        
        
        String orderDateStr = getString("orderDate"); // 订单日期
        paramMap.put("orderDate", orderDateStr);
//        String orderTimeStr = getString("orderTime"); // 订单日期
//        paramMap.put("orderTime", orderTimeStr);
//        String orderPeriodStr = getString("orderPeriod"); // 订单有效期
//        paramMap.put("orderPeriod", orderPeriodStr);
        String returnUrl = getString("returnUrl"); // 页面通知返回url
        paramMap.put("returnUrl", returnUrl);
        String notifyUrl = getString("notifyUrl"); // 后台消息通知Url
        paramMap.put("notifyUrl", notifyUrl);
        String remark = getString("remark"); // 支付备注
        paramMap.put("remark", remark);
        
        String sign = getString("sign"); // 签名

        String field1 = getString("field1"); // 扩展字段1
        paramMap.put("field1", field1);
        String field2 = getString("field2"); // 扩展字段2
        paramMap.put("field2", field2);
        String field3 = getString("field3"); // 扩展字段3
        paramMap.put("field3", field3);
        String field4 = getString("field4"); // 扩展字段4
        paramMap.put("field4", field4);
        String field5 = getString("field5"); // 扩展字段5
        paramMap.put("field5", field5);
        
        try {
        	logger.info("扫码支付,接收参数:{}", JSONObject.toJSONString(httpServletRequest.getParameterMap()));
            if(StringUtils.isEmpty(orderDateStr)) throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单日期不能为空");
            if(StringUtils.isEmpty(payKey)) throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "支付KEY不能为空");
            if(StringUtils.isEmpty(orderAmountStr)) throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单金额不能为空");
            if(StringUtils.isEmpty(orderNo)) throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单编号不能为空");
            if(StringUtils.isEmpty(sign)) throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "签名不能为空");
            if(StringUtils.isEmpty(goodsName)) throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "商品名称不能为空");
	        
	        Date orderDate = DateUtils.parseDate(orderDateStr, "yyyyMMdd");
	       // Date orderTime = DateUtils.parseDate(orderTimeStr, "yyyyMMddHHmmss");
	
	        RpUserPayConfig rpUserPayConfig = rpUserPayConfigService.getByPayKey(payKey);
	        if (rpUserPayConfig == null) {
	            throw new UserBizException(UserBizException.USER_PAY_CONFIG_ERRPR, "用户支付配置有误");
	        }
	        cnpPayService.checkIp(rpUserPayConfig, httpServletRequest);//ip校验
	
	        if (!MerchantApiUtil.isRightSign(paramMap, rpUserPayConfig.getPaySecret(), sign)) {
	            throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "报文签名不正确");
	        }
	
	        BigDecimal orderAmount = null;
	        try {
	        	orderAmount = BigDecimal.valueOf(Double.valueOf(orderAmountStr));
			} catch (Exception e) {
				throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单金额不正确");
			}
	        		
	        ScanPayResultVo scanPayResultVo = rpTradePaymentManagerService.initDirectScanPay(payKey, goodsName, orderNo, orderDate, new Date(), orderAmount, rpUserPayConfig, orderIp, returnUrl
	                , notifyUrl, remark, field1, field2, field3, field4, field5);
	
	        resMap.put("codeUrl", scanPayResultVo.getCodeUrl());//支付二维码
        	resMap.put("orderStatus", TradeStatusEnum.WAITING_PAYMENT.toString()); //
        	resMap.put("orderAmount", orderAmount+"");//订单价格
        	resMap.put("apiCode", PublicEnum.YES.toString()); //默认成功
        	resMap.put("apiMsg", "操作成功"); //默认成功
        	resMap.put("sign", MerchantApiUtil.getSign(resMap, rpUserPayConfig.getPaySecret()));
        } catch (BizException e) {
        	logger.info(orderNo+"支付出现错误："+e.getMessage());
        	resMap.put("apiMsg", e.getMessage()); //默认成功
		}catch (Exception e) {
        	logger.info(orderNo+"支付出现异常:",e);
        	resMap.put("apiMsg", e.getMessage()); //默认成功
		}
        httpServletResponse.setCharacterEncoding("utf-8");
        JsonUtils.responseJson(httpServletResponse, resMap);
    }

    /**
     * 支付结果查询接口
     *
     * @param httpServletResponse
     */
    @RequestMapping("orderQuery")
    public void orderQuery(HttpServletResponse httpServletResponse ,HttpServletRequest httpServletRequest) throws IOException {
    	Map<String, String> resMap = new HashMap<String, String>();
    	resMap.put("apiCode", PublicEnum.NO.toString()); //默认失败
    	resMap.put("apiMsg", "操作失败"); //默认失败
    	
    	Map<String, String> paramMap = new HashMap<String, String>();
        String payKey = getString("payKey"); // 企业支付KEY
        String orderNo = getString("orderNo"); // 订单号
        String sign = getString("sign"); // 签名
        paramMap.put("payKey", payKey);
        paramMap.put("orderNo", orderNo);

        try {
	        RpUserPayConfig rpUserPayConfig = rpUserPayConfigService.getByPayKey(payKey);
	        if (rpUserPayConfig == null) {
	            throw new UserBizException(UserBizException.USER_PAY_CONFIG_ERRPR, "用户支付配置有误");
	        }
	        if (!MerchantApiUtil.isRightSign(paramMap, rpUserPayConfig.getPaySecret(), sign)) {
	            throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单签名异常");
	        }
			RpTradePaymentRecord payResult = rpTradePaymentQueryService.getPayResult(rpUserPayConfig.getUserNo(), orderNo);
	        httpServletResponse.setContentType("text/text;charset=UTF-8");
	        resMap.put("apiCode", PublicEnum.YES.toString()); //默认成功
	        resMap.put("apiMsg", "操作成功"); //默认成功
	        resMap.put("orderStatus", payResult.getStatus()); //
	        resMap.put("orderAmount", payResult.getOrderAmount().toString());
	        resMap.put("orderTime", payResult.getCreateTimeDesc()); 
	        resMap.put("sign", MerchantApiUtil.getSign(resMap, rpUserPayConfig.getPaySecret()));
		} catch (UserBizException e) {
        	logger.info(orderNo+"支付出现错误："+e.getMessage());
        	resMap.put("apiMsg", e.getMessage()); //默认成功
		}catch (Exception e) {
        	logger.info(orderNo+"支付出现异常:",e);
        	resMap.put("apiMsg", e.getMessage()); //默认成功
		}
        JsonUtils.responseJson(httpServletResponse, resMap);
    }

}
